import { inject, injectable } from "inversify";
import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, FileSystemWatcher, Uri } from "vscode";
import { IWorkspaceService } from "../application/types";
import { IPlatformService } from "../platform/types";
import { ICurrentProcess, IDisposableRegistry } from "../types";
import { InMemoryCache } from "../utils/cacheUtils";
import { EnvironmentVariables, IEnvironmentVariablesProvider, IEnvironmentVariablesService } from "./types";

const CACHE_DURATION = 60 * 60 * 1000;
@injectable()
export class EnvironmentVariablesProvider implements IEnvironmentVariablesProvider, Disposable {
  public trackedWorkspaceFolders = new Set<string>();

  private fileWatchers = new Map<string, FileSystemWatcher>();

  private disposables: Disposable[] = [];

  private changeEventEmitter: EventEmitter<Uri | undefined>;

  private readonly envVarCaches = new Map<string, InMemoryCache<EnvironmentVariables>>();

  constructor(
    @inject(IEnvironmentVariablesService) private envVarsService: IEnvironmentVariablesService,
    @inject(IDisposableRegistry) disposableRegistry: Disposable[],
    @inject(IPlatformService) private platformService: IPlatformService,
    @inject(IWorkspaceService) private workspaceService: IWorkspaceService,
    @inject(ICurrentProcess) private process: ICurrentProcess,
    private cacheDuration: number = CACHE_DURATION,
  ) {
    disposableRegistry.push(this);
    this.changeEventEmitter = new EventEmitter();
    const disposable = this.workspaceService.onDidChangeConfiguration(this.configurationChanged, this);
    this.disposables.push(disposable);
  }
  public configurationChanged(e: ConfigurationChangeEvent): void {
    this.trackedWorkspaceFolders.forEach((item) => {
      const uri = item && item.length > 0 ? Uri.file(item) : undefined;
      if (e.affectsConfiguration('python.envFile', uri)) {
        this.onEnvironmentFileChanged(uri);
      }
    });
  }
  private onEnvironmentFileChanged(workspaceFolderUri?: Uri) {
    // An environment file changing can affect multiple workspaces; clear everything and reparse later.
    this.envVarCaches.clear();
    this.changeEventEmitter.fire(workspaceFolderUri);
}
  dispose() {
    throw new Error("111Method not implemented.");
  }
  public get onDidEnvironmentVariablesChange(): Event<Uri | undefined> {
    return this.changeEventEmitter.event;
  }

  getEnvironmentVariables(resource?: Uri): Promise<EnvironmentVariables> {
    throw new Error("112Method not implemented.");
  }
  getCustomEnvironmentVariables(resource?: Uri): Promise<EnvironmentVariables | undefined> {
    throw new Error("113Method not implemented.");
  }
}